repo: Display estimated time remaining when pulling
authorSam Spilsbury <smspillaz@gmail.com>
Wed, 1 Jun 2016 08:15:00 +0000 (08:15 +0000)
committerAtomic Bot <atomic-devel@projectatomic.io>
Wed, 1 Jun 2016 14:09:41 +0000 (14:09 +0000)
Bug 765429 said that not having a time estimate can be annoying
when working with large pulls.

There isn't any complex time estimation logic here - we just take
the number of bytes remaining and do a linear projection of
the bytes per second rate at the current point in time.

Closes: #318
Approved by: cgwalters

src/libostree/ostree-repo.c

index 84907c45acd3db75e624f6e17b239076ce959e4b..36c2ac4462288193d2a1e865ea9ea7095fdcf4d5 100644 (file)
@@ -4170,6 +4170,38 @@ ostree_repo_pull_with_options (OstreeRepo             *self,
 
 #endif
 
+/**
+ * _formatted_time_remaining_from_seconds
+ * @seconds_remaining: Estimated number of seconds remaining.
+ *
+ * Returns a strings showing the number of days, hours, minutes
+ * and seconds remaining.
+ **/
+static char *
+_formatted_time_remaining_from_seconds (guint64 seconds_remaining)
+{
+  guint64 minutes_remaining = seconds_remaining / 60;
+  guint64 hours_remaining = minutes_remaining / 60;
+  guint64 days_remaining = hours_remaining / 24;
+
+  GString *description = g_string_new (NULL);
+
+  if (days_remaining)
+    g_string_append_printf (description, "%lu days ", days_remaining);
+
+  if (hours_remaining)
+    g_string_append_printf (description, "%lu hours ", hours_remaining % 24);
+
+  if (minutes_remaining)
+    g_string_append_printf (description, "%lu minutes ", minutes_remaining % 60);
+
+  if (seconds_remaining)
+    g_string_append_printf (description, "%lu seconds ", seconds_remaining % 60);
+
+  return g_string_free (description, FALSE);
+}
+
+
 /**
  * ostree_repo_pull_default_console_progress_changed:
  * @progress: Async progress
@@ -4225,28 +4257,36 @@ ostree_repo_pull_default_console_progress_changed (OstreeAsyncProgress *progress
       guint fetched = ostree_async_progress_get_uint (progress, "fetched");
       guint metadata_fetched = ostree_async_progress_get_uint (progress, "metadata-fetched");
       guint requested = ostree_async_progress_get_uint (progress, "requested");
-      guint64 bytes_sec = (g_get_monotonic_time () - ostree_async_progress_get_uint64 (progress, "start-time")) / G_USEC_PER_SEC;
+      guint64 start_time = ostree_async_progress_get_uint64 (progress, "start-time");
+      guint64 total_delta_part_size = ostree_async_progress_get_uint64 (progress, "total-delta-part-size");
+      guint64 current_time = g_get_monotonic_time ();
+      guint64 bytes_sec = bytes_transferred / ((current_time - start_time) / G_USEC_PER_SEC);
+      guint64 est_time_remaining =  (total_delta_part_size - bytes_transferred) / bytes_sec;
       g_autofree char *formatted_bytes_transferred =
         g_format_size_full (bytes_transferred, 0);
       g_autofree char *formatted_bytes_sec = NULL;
+      g_autofree char *formatted_est_time_remaining = NULL;
 
       if (!bytes_sec) // Ignore first second
-        formatted_bytes_sec = g_strdup ("-");
+        {
+          formatted_bytes_sec = g_strdup ("-");
+          formatted_est_time_remaining = g_strdup ("- ");
+        }
       else
         {
-          bytes_sec = bytes_transferred / bytes_sec;
           formatted_bytes_sec = g_format_size (bytes_sec);
+          formatted_est_time_remaining = _formatted_time_remaining_from_seconds (est_time_remaining);
         }
 
       if (total_delta_parts > 0)
         {
-          guint64 total_delta_part_size = ostree_async_progress_get_uint64 (progress, "total-delta-part-size");
           g_autofree char *formatted_total =
             g_format_size (total_delta_part_size);
-          g_string_append_printf (buf, "Receiving delta parts: %u/%u %s/s %s/%s",
+          /* No space between %s and remaining, since formatted_est_time_remaining has a trailing space */
+          g_string_append_printf (buf, "Receiving delta parts: %u/%u %s/s %s/%s %sremaining",
                                   fetched_delta_parts, total_delta_parts,
                                   formatted_bytes_sec, formatted_bytes_transferred,
-                                  formatted_total);
+                                  formatted_total, formatted_est_time_remaining);
         }
       else if (outstanding_metadata_fetches)
         {